﻿/*
 * 反射的进阶操作 - 如何反射泛型
 */

using System.Numerics;
using System.Reflection;

var list = new List<string>();
list.Add("Hello");
list.Add("World");

Console.WriteLine(string.Join(" ", list));

//Generic

//Open Generic 开放式泛型   T 未确定之前叫做 开放式泛型
//Close Generic 关闭式泛型  T 确定之后叫做  关闭式泛型

// 使用反射模拟上面的操作

var listType = typeof(List<>).MakeGenericType(typeof(string));
var myList = Activator.CreateInstance(listType);

listType.GetMethod(nameof(List<string>.Add), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)?.Invoke(myList, new object?[] { "MyHello" });

listType.GetMethod(nameof(List<string>.Add), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)?.Invoke(myList, new object?[] { "MyWorld" });


Console.WriteLine(string.Join(" ", (List<string>)myList));


/*
 * 模拟泛型方法
 */

var myClassType = typeof(TestClass);
var myClass = Activator.CreateInstance(myClassType);

myClassType.GetMethod("Add").MakeGenericMethod(typeof(int))?.Invoke(myClass, new object?[] { 1, 2 });
var data = (string)myClassType.GetMethod("AddNew").MakeGenericMethod(typeof(int), typeof(string))
    ?.Invoke(myClass, new object?[] { 1, "2" });
Console.WriteLine(data);


class TestClass
{
    public void Add<T>(T a, T b) where T : INumber<T>
    {
        Console.WriteLine("反射后运算的值是:{0}", a + b);
    }

    public string AddNew<T, TK>(T a, TK b)
        where T : INumber<T>
        where TK : class
    {
        return a.ToString() + b;
    }
}